<?php
	class csrf {
		private $hash_size;
		private $function_hash   = 'sha256';
		private $secret          = 'g!6WJGxdE#ruT^P#';
		private $time_expiration = 4;


		function __construct(int $hash_size = 32) {
			$this -> hash_size = $hash_size;
		}


		// Elimina las variables de sesión.
		private function destroyToken() {
			unset($_SESSION['token'], $_SESSION['expiration']);
		}


		private function errors($message) {
			$this -> destroyToken();

			require_once 'libs/errors.php';

			errors($message);
		}


		// Genera un token en base a bytes aleatorios.
		public function generateToken() {
			$key = bin2hex(random_bytes($this -> hash_size));

			$_SESSION['token']      = hash_hmac($this -> function_hash, $this -> secret, $key);
			$_SESSION['expiration'] = time() + (60 * 60 * $this -> time_expiration);

			return $_SESSION['token'];
		}


		// Valida si el token está expirado y es igual al generado,
		public function validateToken(string $token2) {
			if (empty($_SESSION['token']))
				$this -> errors('No se encontró un token en el formulario');

			if (time() > ((int) $_SESSION['expiration']))
				$this -> errors('El token del formulario ha expirado');

			if (!hash_equals($_SESSION['token'], $token2))
				$this -> errors('Los tokens no coinciden');

			$this -> destroyToken();
		}
	}